#include "model.hpp"
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <GL/glut.h>

using namespace std;

model::model(){
	nbPoints = nbNodes = 0;
}

model::model(const unsigned int &sizeP,const unsigned int &sizeN){
	nbPoints = sizeP;
	nbNodes = sizeN;
	points = Matrix<double>(4,nbPoints);
	nodes = Matrix<int>(3,nbNodes);
}

model::~model(){

}

model* model::importFromFile(string file){
	ifstream fichier(file.c_str(), ios::in);
	unsigned int nbPoint, nbNoeud;
	model *m = NULL;

	if(fichier){
		
		fichier >> nbPoint >> nbNoeud;

		m = new model(nbPoint,nbNoeud);

		for(unsigned int i = 0; i<nbPoint; i++){
			fichier>>m->points[0][i];
			fichier>>m->points[1][i];
			fichier>>m->points[2][i];
			m->points[3][i] = 0;
		}

		for(unsigned int i = 0; i<nbNoeud; i++){
			fichier>>m->nodes[0][i];
			fichier>>m->nodes[1][i];
			fichier>>m->nodes[2][i];
		}

		fichier.close();
	}
	else{ 
		cerr<<"Erreur ouverture de "<<file<<endl;
	}

	return m;
}

void model::applyMatrix(Matrix<double> &m){
	points =  m * points ;
}

void model::drawPixel(int x, int y){
	//On change x et y de repere pour correspondre à la fenetre, on place le point x,y 0,0 au centre de la fenetre
	float lx = 500/2;
	float ly = 500/2;
	float x2 = (x /*- lx*/) / lx ;
	float y2 = (y /*- ly*/) / ly ;
	glVertex2f(x2,y2);
}

void model::drawLine(int x1,int y1,int x2,int y2) {
	int dx,dy,i,xinc,yinc,cumul,x,y ;

	//x,y de départ
	x = x1 ;
	y = y1 ;

	//Distance x et y
	dx = x2 - x1 ;
	dy = y2 - y1 ;

	//Si les différences sont négatives, on parcourt la dimension à l'envers
	xinc = ( dx > 0 ) ? 1 : -1 ;
	yinc = ( dy > 0 ) ? 1 : -1 ;

	//Récupération de la valeur absolue
	dx = abs(dx) ;
	dy = abs(dy) ;

	//Affichage du premier pixel point de départ
	drawPixel(x,y);

	//Test de l'angle de la droite si dx<dy, on applique le traitement de x à y et vice-versa
	if ( dx > dy ) {
		cumul = dx / 2 ;
		for ( i = 1 ; i <= dx ; i++ ) {
			x += xinc ;
			cumul += dy ;
			if (cumul >= dx) {
				cumul -= dx ;
				y += yinc ;
			}
			drawPixel(x,y) ;
		}
	}
	else {
		cumul = dy / 2 ;
		for ( i = 1 ; i <= dy ; i++ ) {
			y += yinc ;
			cumul += dx ;
			if ( cumul >= dy ) {
				cumul -= dy ;
				x += xinc ;
			}
			drawPixel(x,y) ;
		}
	}
}

void model::print() {
	int p1,p2,p3;
	for(unsigned int i = 0;i<nbNodes;i++){
		p1 = nodes[0][i];
		p2 = nodes[1][i];
		p3 = nodes[2][i];
		cout<<"Triangle "<<i<<endl;
		cout<<"Point 1 x:"<<points[0][p1]<<" y:"<<points[1][p1]<<" z:"<<points[2][p1]<<endl;
		cout<<"Point 2 x:"<<points[0][p2]<<" y:"<<points[1][p2]<<" z:"<<points[2][p2]<<endl;
		cout<<"Point 3 x:"<<points[0][p2]<<" y:"<<points[1][p2]<<" z:"<<points[2][p2]<<endl;		
	}
}

void model::draw(){
	int p1,p2,p3;
	glBegin(GL_POINTS);
	for(unsigned int  i = 0; i<nbNodes ; i++){
		p1 = nodes[0][i];
		p2 = nodes[1][i];
		p3 = nodes[2][i];
		this->drawLine(points[0][p1],points[1][p1],points[0][p2],points[1][p2]);
		this->drawLine(points[0][p2],points[1][p2],points[0][p3],points[1][p3]);
		this->drawLine(points[0][p3],points[1][p3],points[0][p1],points[1][p1]);
	}
	glEnd();
}

